#ifndef __FRAME__RENDERER__H__
#define __FRAME__RENDERER__H__

#include "FrameCanvas.h"
#include "ThreadPipe.h"
#include "EglImpl.h"
#include "PicFrame.h"
#include "GLRenderer.h"

#ifdef __ANDROID__
#include "jni_utils.h"
#endif

namespace simple_renderer{

typedef struct _RenderParam{
    FrameType frame_type;
    RenderMode render_mode;

    _RenderParam(){}

    _RenderParam(const _RenderParam &param){
        frame_type = param.frame_type;
        render_mode = param.render_mode;
    }

    _RenderParam& operator=(const _RenderParam &param){
        if(this == &param){
            return *this;
        }
        frame_type = param.frame_type;
        render_mode = param.render_mode;
        return *this;
    }

} RenderParam;

class FrameRenderer{

public:
    FrameRenderer();
    virtual ~FrameRenderer();

    int StartRender();
    int StopRender();

#ifdef __ANDROID__
    int UpdateAndroidFrameWindow(std::shared_ptr<JavaGlobalRef<jobject>> frameCanvas, RenderParam &param);
    void MoveIntoAndroidWindowEventWrapper(std::shared_ptr<JavaGlobalRef<jobject>> event_wrapper);
    std::shared_ptr<JavaGlobalRef<jobject>> MoveOutAndroidWindowEventWrapper();
#endif

    int CreatWindow();
    int ResizeWindow(int win_w, int win_h);
    int DestoryWindow();

    void DrawFrame(int pic_w, int pic_h, uint8_t *frame_data, int frame_len, FrameType type);
    void DrawFrameI420(int w, int h, FrameType type, uint8_t* data_y, int len_y, uint8_t* data_u, int len_u, uint8_t* data_v, int len_v);
    void DestorySurface();

protected:
    //run on OpenGL thread
    void InitGLEnvInThread(MessageData * msg);
    void DrawFrameInThread(MessageData * msg);
    void DeinitGLEnvInThread(MessageData * msg);

    void DestorySurfaceInThread(MessageData * msg);
protected:
    std::unique_ptr<ThreadPipe> _thread_pip;
    std::unique_ptr<BaseEgl> _egl_impl;
    std::unique_ptr<GLRenderer> _gl_renderer;
    std::unique_ptr<PicFrame> _pic_frame;

    RenderParam _render_param;

    /** for copy frame and draw frame */
    std::mutex _frame_mux;
    std::mutex _draw_mux;
    std::mutex _egl_mux;

    int _win_w, _win_h;
    bool _surface_ready;

#ifdef __ANDROID__
    //Android java platform window
    //1.hold it  2.pass to egl to create OpenGL env
    std::shared_ptr<JavaGlobalRef<jobject>> _frame_window_ref;
    //Android SurfaceEventWrapper
    //1.hold it, when FrameRenderer destory, remove window_event_wrapper(created by jni)
    // from java window
    std::shared_ptr<JavaGlobalRef<jobject>> _window_event_wrapper_ref;
#endif

};
}
#endif